package org.example;

import cn.hutool.core.lang.Console;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.grpc.stub.StreamObserver;
import lombok.SneakyThrows;
import org.example.model.TestProto;
import org.example.service.TestFirstService;

import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

// TIP 要<b>运行</b>代码，请按 <shortcut actionId="Run"/> 或
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
public class StudyGrpc2ClientMain {


    // 使用jackson进行转成 json字符串
    static ObjectMapper mapper = new ObjectMapper();

    static {
        mapper.findAndRegisterModules();
    }

    @SneakyThrows
    public static void main(String[] args) {
        // testHttp();

        // testSSE();

        // testSSEReal();


        // testClientStreamReal();

        testHelloWorldByWebSocket();
    }

    @SneakyThrows
    public static void testHttp() {
        TestFirstService testFirstService = new TestFirstService();

        // 接口请求参数
        TestProto.RequestData requestData = TestProto.RequestData.newBuilder()
                .setMethod("get")
                .setNeedStatus(TestProto.StatusEnum.SUCCESS)
                .build();

        // 发起请求并获取结果
        TestProto.ResponseData responseData = testFirstService.helloWorld(requestData);

        // 打印结果
        Console.log("远程执行结果：{}", mapper.writeValueAsString(responseData));
    }


    @SneakyThrows
    public static void testSSE() {
        TestFirstService testFirstService = new TestFirstService();

        // 接口请求参数
        TestProto.RequestData requestData = TestProto.RequestData.newBuilder()
                .setMethod("get")
                .setNeedStatus(TestProto.StatusEnum.SUCCESS)
                .build();

        // 发起请求并获取结果
        Iterator<TestProto.ResponseData> responseDataIterator = testFirstService.helloWorldBySSE(requestData);

        Integer messageCount = 0;
        while (responseDataIterator.hasNext()) {
            TestProto.ResponseData next = responseDataIterator.next();
            Console.log("结果到消息{}：{}", ++messageCount, mapper.writeValueAsString(next));
        }

    }

    @SneakyThrows
    public static void testSSEReal() {
        TestFirstService testFirstService = new TestFirstService();

        // 接口请求参数
        TestProto.RequestData requestData = TestProto.RequestData.newBuilder()
                .setMethod("get")
                .setNeedStatus(TestProto.StatusEnum.SUCCESS)
                .build();

        // 发起请求并获取结果
        CountDownLatch countDownLatch = testFirstService.helloWorldBySSEReal(requestData);
        countDownLatch.await();

        Console.log("======结束======");
    }


    @SneakyThrows
    public static void testClientStreamReal() {
        TestFirstService testFirstService = new TestFirstService();

        StreamObserver<TestProto.RequestData> requestDataStreamObserver = testFirstService.helloWorldByClientStreamRpc();


        int requestMessageCount = RandomUtil.randomInt(2, 5);

        // 客户端消息发送
        for (int messageCount = 0; messageCount < requestMessageCount; messageCount++) {
            TestProto.RequestData requestData = TestProto.RequestData.newBuilder()
                    .setMethod(StrUtil.format("get_{}", messageCount))
                    .setNeedStatus(TestProto.StatusEnum.SUCCESS)
                    .build();
            requestDataStreamObserver.onNext(requestData);
        }

        // 客户端消息发送完毕
        requestDataStreamObserver.onCompleted();


        ThreadUtil.sleep(10, TimeUnit.SECONDS);
    }


    @SneakyThrows
    public static void testHelloWorldByWebSocket() {
        TestFirstService testFirstService = new TestFirstService();

        StreamObserver<TestProto.RequestData> requestDataStreamObserver = testFirstService.helloWorldByWebSocket();


        int requestMessageCount = RandomUtil.randomInt(2, 5);

        // 客户端消息发送
        for (int messageCount = 0; messageCount < requestMessageCount; messageCount++) {
            TestProto.RequestData requestData = TestProto.RequestData.newBuilder()
                    .setMethod(StrUtil.format("get_{}", messageCount))
                    .setNeedStatus(TestProto.StatusEnum.SUCCESS)
                    .build();
            requestDataStreamObserver.onNext(requestData);
        }

        // 客户端消息发送完毕
        requestDataStreamObserver.onCompleted();


        ThreadUtil.sleep(10, TimeUnit.SECONDS);
    }
}